package com.activiti;

import com.redpig.App;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;

@SpringBootTest(classes = App.class)
public class Activiti01 {

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    /**
     * 流程部署操作
     */
    @Test
    public void testDeploy(){
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("task/oa-leave.bpmn20.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deploy = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)
                //.addClasspathResource("task/oa-leave.bpmn20.xml")
                .name("请假流程部署")
                .deploy(); // 是一个流程部署的行为 可以部署多个流程定义的
        System.out.println("deploy.getId() = " + deploy.getId());
        System.out.println("deploy.getName() = " + deploy.getName());
    }

    @Test
    public void test(){

        List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().listPage(0, 10);
        System.out.println(processDefinitions);
    }

    /**
     * 查询当前部署的流程有哪些
     */
    @Test
    public void testFindDeploy(){
        // 查询有哪些部署的流程--》查询相关的流程定义信息
        // repositoryService.createDeploymentQuery() 查询流程部署的相关信息
        // repositoryService.createProcessDefinitionQuery() 查询部署的流程的相关的定义
        List<Deployment> list = repositoryService.createDeploymentQuery().list(); // 查询所有的部署信息

        System.out.println("部署信息:");
        for (Deployment deployment : list) {
            System.out.println("deployment.getId() = " + deployment.getId());
            System.out.println("deployment.getName() = " + deployment.getName());
            System.out.println("deployment.getDeploymentTime() = " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(deployment.getDeploymentTime()));
        }
        System.out.println("流程定义信息:");
        List<ProcessDefinition> list1 = repositoryService.createProcessDefinitionQuery().list();
        for (ProcessDefinition processDefinition : list1) {
            System.out.println("----------------------------------------------------------------");
            System.out.println("processDefinition.getId() = " + processDefinition.getId());
            System.out.println("processDefinition.getName() = " + processDefinition.getName());
            System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
        }
    }

    /**
     * 删除部署的流程
     */
    @Test
    public void testDeleteDelopy(){
        List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
        for (Deployment deployment : deployments) {
            repositoryService.deleteDeployment(deployment.getId());
        }
    }

    /**
     * 发起一个流程
     */
    @Test
    public void testStart(){
        // 发起流程 需要通过 runtimeService来实现
        // 绑定对应的请假天数
        Map<String,Object> map = new HashMap<>();
        map.put("days",5);
        map.put("leave_reason","调休3天");
        // 通过流程定义ID来启动流程  返回的是流程实例对象
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceById("oa-leave:1:e6aa7270-25f1-11ee-ac8d-1c1b0d7e2515",map);
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
        taskService.addComment(task.getId(),processInstance.getProcessInstanceId(),"请假回家旅游");
        System.out.println("processInstance.getId() = " + processInstance.getId());
        System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
        System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
    }

    /**
     * 查询所有任务
     */
    @Test
    public void test4(){
        List<Task> list = taskService.createTaskQuery().list();
        for (Task task : list) {
            System.out.println("task.getId() = " + task.getId());
            System.out.println("task.getName() = " + task.getName());
            System.out.println("task.getExecutionId() = " + task.getExecutionId());
            System.out.println("task.getDescription() = " + task.getDescription());
            System.out.println("task.getAssignee() = " + task.getAssignee());
            System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId());
            System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());
            String processDefinitionId = task.getProcessDefinitionId();
            ProcessDefinitionEntity	processDefinitionEntity=(ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);
            String processInstanceId=task.getProcessInstanceId();
            ProcessInstance pi=runtimeService.createProcessInstanceQuery() // 根据流程实例id获取流程实例
                    .processInstanceId(processInstanceId)
                    .singleResult();
            System.out.println("pi.getProcessInstanceId() = " + pi.getProcessInstanceId());
            System.out.println("***********task comment***********");
            for (Comment taskComment : taskService.getTaskComments(task.getId())) {
                System.out.println("taskComment.getFullMessage() = " + taskComment.getFullMessage());
            }
            System.out.println("***********task comment***********");
            runtimeService.deleteProcessInstance(processInstanceId, "任务被强制终止");
        }
    }

    /**
     * 查看任务
     */
    @Test
    public void test5(){
        Task task = taskService.createTaskQuery().taskAssignee("CTO").singleResult();
        System.out.println("task.getAssignee() = " + task.getAssignee());

        /*Task task = taskService.createTaskQuery().taskAssignee("CTO").singleResult();
        Map<String,Object> variables = new HashMap<>();
        variables.put("agree","0");
        taskService.complete(task.getId(),variables);*/
        /*List<Task> list = taskService.createTaskQuery().list();
        for (Task task : list) {
            taskService.complete(task.getId());
        }*/
    }
}
